package org.hackystat.storageservice.resources;

import org.hackystat.storageservice.db.derby.DerbyFacade;
import org.hackystat.storageservice.resources.alt.Util;
import org.hackystat.utilities.stacktrace.StackTrace;
import org.restlet.Context;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.Representation;
import org.restlet.resource.Resource;
import org.restlet.resource.Variant;

/**
 * Implements a resource for PUT, GET, DELETE of host/sensordatatype/{sensordatatypename}.
 *
 * @author Philip Johnson
 */
public class SensorDataTypeResource extends Resource {

    /**
     * To be retrieved from the URL.
     */
    private String sdtName;
    private DerbyFacade db;
    private Util util;


    /**
     * Provides the following representational variants: TEXT_XML.
     *
     * @param context  The context.
     * @param request  The request object.
     * @param response The response object.
     */
    public SensorDataTypeResource(Context context, Request request, Response response) {
        super(context, request, response);
        this.sdtName = (String) request.getAttributes().get("sensordatatypename");
        this.util = new Util(request, response);
        db = (DerbyFacade) getContext().getAttributes().get("DerbyFacade");
        getVariants().clear();
        getVariants().add(new Variant(MediaType.TEXT_XML));
    }

    /**
     * Returns the representation of the specified SensorDataType resource.
     *
     * @param variant The representational variant requested.
     * @return The representation.
     */
    @Override
    public Representation represent(Variant variant) {
        if (variant.getMediaType().equals(MediaType.TEXT_XML)) {
            String xmlData = db.getSensorDataType(this.sdtName);
            return Util.getStringRepresentation(xmlData);
        }
        return null;
    }

    /**
     * Indicate the PUT method is supported.
     *
     * @return True.
     */
    @Override
    public boolean allowPut() {
        return true;
    }

    /**
     * Implement the PUT method that creates a new SDT.
     * <ul>
     * <li> The XML must be marshallable into an SDT instance using the SDT XmlSchema definition.
     * <li> The SDT name in the URI string must match the SDT name in the XML.
     * <li> The authenticated user must be the admin.
     * </ul>
     *
     * @param entity The XML representation of the new SDT.
     */
    @Override
    public void storeRepresentation(Representation entity) {

        try {
            try {
                Form form = getRequest().getEntityAsForm();

                String sdtString = form.getFirstValue("sdtXml");
                String sdtRefString = form.getFirstValue("sdtXmlRef");
                db.storeSensorDataType(sdtName, sdtString, sdtRefString);
                getResponse().setStatus(Status.SUCCESS_CREATED);
            }
            catch (Exception e) {
                System.out.println("Failed to put SDT" + StackTrace.toString(e));
            }
        }
        catch (RuntimeException e) {
            util.setStatusInternalError(e);
        }
    }

    /**
     * Indicate the DELETE method is supported.
     *
     * @return True.
     */
    @Override
    public boolean allowDelete() {
        return true;
    }

    /**
     * Implement the DELETE method that deletes an existing SDT given its name.
     */
    @Override
    public void removeRepresentations() {
        try {
            db.deleteSensorDataType(sdtName);
            getResponse().setStatus(Status.SUCCESS_OK);
        }
        catch (RuntimeException e) {
            util.setStatusInternalError(e);
        }
    }
}
